package cn.sirun.com.fca.account.view.impl;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.tencent.captchasdk.TCaptchaDialog;
import com.tencent.captchasdk.TCaptchaVerifyListener;
import com.tencent.cloud.iov.flow.view.IContentViewContainer;
import com.tencent.cloud.iov.kernel.IovKernel;
import com.tencent.cloud.iov.kernel.constant.StatusCode;
import com.tencent.cloud.iov.kernel.model.BaseResponse;
import com.tencent.cloud.iov.kernel.util.CookieUtils;
import com.tencent.cloud.iov.router.Router;
import com.tencent.cloud.iov.util.ActivityUtils;
import com.tencent.cloud.iov.util.PatternMatchingUtils;
import com.tencent.cloud.iov.util.ResourcesUtils;
import com.tencent.cloud.iov.util.SRPUtils;
import com.tencent.cloud.iov.util.crypt.CustomSRPClient;
import com.tencent.cloud.iov.util.storage.TXCacheManager;
import com.tencent.cloud.iov.util.storage.TXSharedPreferencesUtils;
import com.tencent.cloud.uikit.utils.DialogUtils;
import com.tencent.cloud.uikit.widget.edittext.LineEditText;
import com.tencent.cloud.uikit.widget.edittext.LineTwoEditText;
import com.tencent.cloud.uikit.widget.edittext.PasswordEditText;
import com.tencent.cloud.uikit.widget.edittext.PhoneMailEditText;
import com.tencent.mars.xlog.Log;

import org.json.JSONException;
import org.json.JSONObject;

import cn.sirun.com.fca.account.R;
import cn.sirun.com.fca.account.constant.AccountActivityConst;
import cn.sirun.com.fca.account.constant.AccountCommonConst;
import cn.sirun.com.fca.account.constant.AccountIntentConst;
import cn.sirun.com.fca.account.constant.AccountStatusCode;
import cn.sirun.com.fca.account.constant.CaptchaConst;
import cn.sirun.com.fca.account.constant.CarConst;
import cn.sirun.com.fca.account.constant.RequestParamConst;
import cn.sirun.com.fca.account.model.base.Captcha;
import cn.sirun.com.fca.account.model.base.CarInfoDetailResponse;
import cn.sirun.com.fca.account.model.login.AuthenticateRequest;
import cn.sirun.com.fca.account.model.login.AuthenticateResponse;
import cn.sirun.com.fca.account.model.login.ChallengeRequest;
import cn.sirun.com.fca.account.model.login.ChallengeResponse;
import cn.sirun.com.fca.account.model.login.LoginResponse;
import cn.sirun.com.fca.account.model.login.PersonalInfo;
import cn.sirun.com.fca.account.model.login.PersonalInfoRequest;
import cn.sirun.com.fca.account.model.login.VehicleRespons;
import cn.sirun.com.fca.account.presenter.ILoginPresenter;
import cn.sirun.com.fca.account.presenter.impl.LoginPresenter;
import cn.sirun.com.fca.account.service.LoginManager;
import cn.sirun.com.fca.account.uitl.AccountStatusUtils;
import cn.sirun.com.fca.account.uitl.CurCarInfoUtils;
import cn.sirun.com.fca.account.uitl.GsonHelper;
import cn.sirun.com.fca.account.uitl.PersonalInfoUtils;
import cn.sirun.com.fca.account.view.ILoginView;

public class LoginFlowView extends AccountBaseLoadingFlowView<ILoginPresenter>
        implements View.OnClickListener, ILoginView {

    private static final String TAG = LoginFlowView.class.getSimpleName();

    private TextView mRegisterTV, mPhoneTV, mPassTV, mForgetPassTV, mLoginTV;
    private PasswordEditText mPassET;
    private PhoneMailEditText mPhoneET;
    private Button mWXLoginBtn;
    private ImageView mPhoneIV, mPassIV;
    private View mPassV, mPhoneV;

    private CustomSRPClient mCustomSRPClient;
    private String mPhone;
    private String mPassword;
    private TCaptchaDialog mTCaptchaDialog = null;
    private boolean isLoginRequest = false;
    private boolean mIsPhone;

    public LoginFlowView(Activity activity) {
        this(activity, null);
    }

    public LoginFlowView(Activity activity, IContentViewContainer container) {
        super(activity, container);
        mCustomSRPClient = SRPUtils.getCustomSRPClient();
        CookieUtils.clear();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        initView();
    }

    @Override
    public void onChallengeResult(BaseResponse<ChallengeResponse> response) {
        int code = response.getCode();
        if (StatusCode.SUCCESS == code) {
            ChallengeResponse challengeResponse = response.getData();
            String salt = challengeResponse.getSalt();
            String group = challengeResponse.getGroup();
            String publicKey = challengeResponse.getPublicKey();
            String[] authenticateInfo = SRPUtils.generateAuthenticateInfo(mCustomSRPClient,
                    mPassword, salt, group, publicKey);
            if (null == authenticateInfo) {
                hideLoadingView();
                DialogUtils.showToast(getActivity(), R.string.common_request_failed);
                return;
            }
            TXCacheManager.getInstance().put(SRPUtils.SRP_SALT, challengeResponse.getSalt());
            TXCacheManager.getInstance().put(SRPUtils.SRP_GROUP, challengeResponse.getGroup());
            TXCacheManager.getInstance().put(SRPUtils.SRP_SERVER_PUBLIC_KEY,
                    challengeResponse.getPublicKey());
            getPresenter().authenticate(new AuthenticateRequest(authenticateInfo[0],
                    authenticateInfo[1]));
        } else if (AccountStatusCode.NEED_VERIFY == code) {
            hideLoadingView();
            showCaptchaDialog();
        } else {
            hideLoadingView();
            AccountStatusUtils.showToast(getActivity(), code);
        }
    }

    @Override
    public void passwordLogin(BaseResponse<LoginResponse> response) {

    }

    @Override
    public void onAuthenticateResult(BaseResponse<AuthenticateResponse> response) {
//        hideLoadingView();
        int code = response.getCode();
        if (StatusCode.SUCCESS == code) {
            String serverEvidenceMessage = response.getData().getEvidenceMessage();
            if (!SRPUtils.verifyEvidenceMessage(mCustomSRPClient, serverEvidenceMessage)) {
                DialogUtils.showToast(getActivity(), R.string.common_request_failed);
                return;
            }
            handleLoginSuccess(response.getData());
            PersonalInfoRequest request = new PersonalInfoRequest(
                    IovKernel.getQQAppId(), IovKernel.getWeChatAppId()
            );
            getPresenter().getPersonalInfo(request);
        } else if (AccountStatusCode.USERNAME_OR_PWD_ERROR == code) {
            DialogUtils.showDialog(getActivity(), R.string.dialog_title_error_message,
                    R.string.dialog_login_fail_message,
                    ResourcesUtils.getString(R.string.dialog_i_know), null,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    }, null);
        } else {
            AccountStatusUtils.showToast(getActivity(), code);
        }
    }

    @Override
    public void getVehicle(BaseResponse<VehicleRespons> response) {
        Log.d(TAG, response.getData().getCarList().get(0).getDin());
    }

    @Override
    public void onPersonalInfoResult(BaseResponse<PersonalInfo> response) {
        int code = response.getCode();
        if (code == StatusCode.SUCCESS) {
            PersonalInfo personInfo = response.getData();
            handlePersonalInfoResult(personInfo);
        } else {
            hideLoadingView();
            turnToMainActivity();
        }
    }

    private void handlePersonalInfoResult(PersonalInfo personInfo) {
        PersonalInfoUtils.savePersonalInfo(personInfo);
        if (!TextUtils.isEmpty(personInfo.getIovCurrentVehicle())) {
            TXSharedPreferencesUtils.setValue(CarConst.SpKey.CAR_ACTIVATE_INFO,
                    personInfo.getIovCurrentVehicle());
            getPresenter().getCarInfo(personInfo.getIovCurrentVehicle());
        } else {
            hideLoadingView();
        }
    }

    @Override
    public void onCarInfoResult(BaseResponse<CarInfoDetailResponse> response) {
        int code = response.getCode();
        if (code == StatusCode.SUCCESS) {
            handleCarInfoResult(response.getData());
        }
        hideLoadingView();
        turnToMainActivity();
    }

    private void handleCarInfoResult(CarInfoDetailResponse carInfo) {
        if (carInfo.getReseller() != null) {
            PersonalInfo personalInfo = PersonalInfoUtils.getPersonalInfo();
            personalInfo.setReseller(carInfo.getReseller());
            PersonalInfoUtils.savePersonalInfo(personalInfo);
        }
        CurCarInfoUtils.saveCarInfo(carInfo);
    }

    @Override
    protected ILoginPresenter createPresenter() {
        return new LoginPresenter();
    }

    private void initView() {
        setContentView(R.layout.login_activity);
        final Activity activity = getActivity();
        mRegisterTV = activity.findViewById(R.id.tv_register);
        mPhoneTV = activity.findViewById(R.id.tv_phone);
        mPassTV = activity.findViewById(R.id.tv_pass);
        mForgetPassTV = activity.findViewById(R.id.tv_forget_pass);
        mLoginTV = activity.findViewById(R.id.tv_login);

        mPassET = activity.findViewById(R.id.et_pass_number);
        mPhoneET = activity.findViewById(R.id.et_phone_number);

        mWXLoginBtn = activity.findViewById(R.id.btn_wx_login);

        mPhoneIV = activity.findViewById(R.id.iv_phone_prompt);
        mPassIV = activity.findViewById(R.id.iv_pass_prompt);

        mPassV = activity.findViewById(R.id.v_pass_line);
        mPhoneV = activity.findViewById(R.id.v_pheon_line);

        mRegisterTV.setOnClickListener(this);
        mLoginTV.setOnClickListener(this);
        mForgetPassTV.setOnClickListener(this);
        mWXLoginBtn.setOnClickListener(this);

        registerListener();
    }

    private void registerListener() {
        mPhoneET.setCheckFormatListener(new LineTwoEditText.OnCheckFormatListener() {
            @Override
            public void onSuccess() {
                setPhoneEmailBg(R.string.tv_title_phone_mail, R.color.login_input_text_color,
                        R.color.divider_bg_color, View.GONE);
            }

            @Override
            public void onFailed() {
                setPhoneEmailBg(R.string.tv_phone_email_error, R.color.login_register_text_color,
                        R.color.login_register_text_color, View.VISIBLE);
            }
        });

        mPhoneET.setTextChangeListener(new LineTwoEditText.OnTextChangeListener() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                setConfirmBtnEnable();
            }
        });

        mPassET.setTextChangeListener(new LineEditText.OnTextChangeListener() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                setConfirmBtnEnable();
            }
        });

    }

    private void setPhoneEmailBg(int text, int textColor, int LineColor, int visibility) {
        mPhoneTV.setText(ResourcesUtils.getString(text));
        mPhoneTV.setTextColor(ResourcesUtils.getColor(textColor));
        mPhoneV.setBackgroundColor(ResourcesUtils.getColor(LineColor));
        mPhoneIV.setVisibility(visibility);
    }

    private void setPassBg(int text, int textColor, int LineColor, int visibility) {
        mPassTV.setText(ResourcesUtils.getString(text));
        mPassTV.setTextColor(ResourcesUtils.getColor(textColor));
        mPassV.setBackgroundColor(ResourcesUtils.getColor(LineColor));
        mPassIV.setVisibility(visibility);
    }

    private void setConfirmBtnEnable() {

        String phone = mPhoneET.getText().toString();
        String password = mPassET.getText().toString();
        int passwordLength = mPassET.length();
        int phoneEmailLength = mPhoneET.length();

        boolean isPhoneCorrect = PatternMatchingUtils.isTelephoneOrEmailCorrect(phone);
        boolean isInputPasswordCorrect = PatternMatchingUtils.isPasswordCorrect(password);

        boolean isEnable = (passwordLength >= PasswordEditText.MIN_LENGTH
                && isPhoneCorrect);

        if (0 == phoneEmailLength || isPhoneCorrect) {
            setPhoneEmailBg(R.string.tv_title_phone_mail, R.color.login_input_text_color,
                    R.color.divider_bg_color, View.GONE);
        }

        if (0 == passwordLength || isInputPasswordCorrect) {
            setPassBg(R.string.tv_title_pass, R.color.login_input_text_color,
                    R.color.divider_bg_color, View.GONE);
        }

        if (isEnable) {
            mLoginTV.setBackgroundResource(R.drawable.s_btn_bg_border);
        } else {
            mLoginTV.setBackgroundResource(R.drawable.s_btn_default_bg_border);
        }
        mLoginTV.setEnabled(isEnable);
    }

    private boolean checkFormat() {
        String password = mPassET.getText().toString();
        String phone = mPhoneET.getText().toString();
        boolean isInputPasswordCorrect = PatternMatchingUtils.isPasswordCorrect(password);
        boolean isPhoneCorrect = PatternMatchingUtils.isTelephoneOrEmailCorrect(phone);
        if (isInputPasswordCorrect && isPhoneCorrect) {
            return true;
        } else {
            if (!isInputPasswordCorrect) {
                setPassBg(R.string.tv_pass_notice, R.color.login_register_text_color,
                        R.color.login_register_text_color, View.VISIBLE);
            }

            if (!isPhoneCorrect) {
                setPhoneEmailBg(R.string.tv_phone_email_error, R.color.login_register_text_color,
                        R.color.login_register_text_color, View.VISIBLE);
            }
            return false;
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (AccountCommonConst.FINISH_PREVIOUS_ACTIVITY_RESULT_CODE == resultCode) {
            getActivity().finish();
        } else if (AccountCommonConst.TURN_TO_MAIN_ACTIVITY_RESULT_CODE == resultCode) {
//            if (AccountIntentConst.MODIFY_LOGIN_PASSWORD == mFrom) {
//                getActivity().finish();
//            } else {
            turnToMainActivity();
//            }
        } else if (AccountCommonConst.QQ_AUTH_REQUEST_CODE == requestCode) {
//            handleActivityResult(requestCode, resultCode, data);
        }
    }

    public void turnToMainActivity() {
        Intent intent = Router.fromPath(AccountActivityConst.Path.MAIN);
        ActivityUtils.startActivity(getActivity(), intent);
        getActivity().finish();
    }

    private void handleLoginSuccess(LoginResponse response) {
        LoginManager.getInstance().handleLoginSuccess(response);
//        getPresenter().getVehicle();
//        turnToMainActivity();
//        if (AccountIntentConst.OPEN_BIND_LOGIN == mFrom) {
//            //互联登录绑定跳转过来的登录，发送onBind请求
//            getPresenter().openBind(mBindRequest);
//        } else {
//            // 若是登录态失效，则销毁当前界面，转回失效前界面
//            if (AccountCommonConst.FINISH_PREVIOUS_ACTIVITY_RESULT_CODE == mFrom
//                    || AccountIntentConst.MODIFY_LOGIN_PASSWORD == mFrom) {
//                getActivity().finish();
//            } else {
//                // 若为正常登录（非登录态失效），则跳转到首页
//                turnToMainActivity();
//            }
//        }
    }

    private void handleLoginClick() {
        if (!checkFormat()) {
            return;
        }

        mPhone = mPhoneET.getText().toString();
        mPassword = mPassET.getText().toString();
        mIsPhone = PatternMatchingUtils.isTelephoneCorrect(mPhone);
        showLoadingView();
        // V2版采用SRP方式加密，不再需要获取RSA公钥
        // 先获取盐等信息，成功后，再获取客户端置信证明
        if (mIsPhone) {
            getPresenter().challenge(new ChallengeRequest(RequestParamConst.DEFAULT_NATION_CODE, mPhone));
        } else {
            getPresenter().challenge(new ChallengeRequest(mPhone));
        }

    }

    private void showCaptchaDialog() {
        mTCaptchaDialog = new TCaptchaDialog(getActivity(), CaptchaConst.APP_ID, new
                TCaptchaVerifyListener() {
                    @Override
                    public void onVerifyCallback(JSONObject jsonObject) {
                        try {
                            int ret = jsonObject.getInt(RequestParamConst.RET);
                            if (StatusCode.SUCCESS == ret) {
                                String ticket = jsonObject.optString(RequestParamConst.TICKET);
                                String randStr = jsonObject.optString(RequestParamConst.RAND_STR);
                                ChallengeRequest request;
                                if (mIsPhone) {
                                    request = new ChallengeRequest(RequestParamConst.DEFAULT_NATION_CODE, mPhone,
                                            new Captcha(randStr, ticket));
                                } else {
                                    request = new ChallengeRequest(mPhone, new Captcha(randStr, ticket));
                                }
                                getPresenter().challenge(request);
                                showLoadingView();
                            } else {
                                DialogUtils.showToast(getActivity(),
                                        R.string.common_request_failed);
                            }
                        } catch (JSONException e) {
                            DialogUtils.showToast(getActivity(), R.string.common_request_failed);
                        }
                    }
                }, null);
        mTCaptchaDialog.show();
    }

    private void registerIntent() {
        String path = AccountActivityConst.Path.PHONE;
        Intent intent = Router.fromPath(path);
        intent.putExtra(AccountIntentConst.FROM, AccountIntentConst.REGISTER);
        getActivity().startActivity(intent);
    }

    private void forgetPassIntent() {
        String path = AccountActivityConst.Path.PHONE;
        Intent intent = Router.fromPath(path);
        intent.putExtra(AccountIntentConst.FROM, AccountIntentConst.FORGET_PASSWORD);
        getActivity().startActivity(intent);
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        if (id == R.id.tv_register) {
            registerIntent();
        } else if (id == R.id.tv_forget_pass) {
            forgetPassIntent();
        } else if (id == R.id.tv_login) {
            handleLoginClick();
        } else if (id == R.id.btn_wx_login) {
            thirdLoginIntent();
        }
    }

    private void messageIntent() {
        String path = AccountActivityConst.Path.AUTHENTICATION;
        Intent intent = Router.fromPath(path);
        getActivity().startActivity(intent);
    }


    private void thirdLoginIntent() {
        String path = AccountActivityConst.Path.THIRDLOGIN_ONE;
        Intent intent = Router.fromPath(path);
        getActivity().startActivity(intent);
    }
}
